<template>
  <div class="Excelview">
     <div class="con">
         <input  type="file" ref="dianfileInput222" accept=".xls"   @change="handleFileUploadxls"  style="display: none">
        <div class="mydiodiv" style="margin-top:20px;display: flex;align-items: center;">
             <el-button  class="last-el-button" type="primary" style="width:100px" @click="openDaorufnxls">选择Excel模板</el-button>
        </div>
        <div class="el-loading-mask" v-show="isMask">
             <div class="el-loading-spinner"><svg viewBox="25 25 50 50" class="circular"> <circle cx="50" cy="50" r="20" fill="none" class="path"></circle></svg></div>
          </div>
     </div>
  </div>
</template>

<script>
import {getChannelconfigidleNumber,getDeviceconfigidleNumber} from "../api/forwardApi";
import {addDevicechun,commonAppTypeGroup,GenerateNumfn} from "../api/Interface";
import {addDeviceGroup,findDeviceGroupListAll,addDeviceTemplate,addSerialType,addModbusArea,findAreaQuery,addModbusItem,channelconfigAdd,findchannelconfigAll} from "../api/dataComparisonApi";
import * as XLSX from 'xlsx';
import { useCounterStore } from '../stores/counter'
export default {

  data() {
    return {
      isMask:false,
      jsonData:[],
      tongdaoshebeiData:[],
      gudingchannel_number:"",
      gudingchannel_numbershebei:"",
      device_template_name:"",//设备模板名称
      waijieshebeizu:[],
      shebeizuArr:[],
      shebeizixilieArr:[],
      nowshebeizixilieObj:{},
      nowtongdaoObj:{},
      typeGroupAll:[],
      typeGroup:[],
    };
  },

  mounted() {
     this.getChannelconfigidleNumberfn()
     this.getDeviceconfigidleNumberfn()
     this.getcommonAppTypeGroup()
    //  console.log("数据类型",this.dataTypeList);
  },
  computed: {
    dataTypeList(){
        return useCounterStore().mydataType
    },
},

  methods: {
       //获取应用类型组
        getcommonAppTypeGroup(){
            commonAppTypeGroup().then(res => {
                //   this.typeGroup = res
                if(res != undefined){
                    this.typeGroupAll = res
                    this.typeGroup = res.filter(item => item.pid === 0)

                }
            })
        },
     //查询空闲的通道号
        getChannelconfigidleNumberfn(){
            getChannelconfigidleNumber().then(res => { 
                if(res != undefined){
                this.gudingchannel_number = res.idle
                }
            })
        },
        //查询空闲的设备号
        getDeviceconfigidleNumberfn(){
            getDeviceconfigidleNumber().then(res => { 
                if(res != undefined){
                this.gudingchannel_numbershebei = res.idle
                }
            })
        },
     //导入外部xls表格文件
        openDaorufnxls(){
            this.$refs.dianfileInput222.click();
            // this.daorushebeimuban = true
        },
        handleFileUploadxls(event) {
        const file = event.target.files[0];
        if (!file) return;

        const reader = new FileReader();
        reader.onload = (e) => {
            const data = new Uint8Array(e.target.result);
            const workbook = XLSX.read(data, { type: 'array' });

            // 获取第一个工作表
            const firstSheetName = workbook.SheetNames[0];
            const worksheet = workbook.Sheets[firstSheetName];

            // 处理合并单元格（关键步骤）
            if (worksheet['!merges']) {
            worksheet['!merges'].forEach((merge) => {
                const startCell = XLSX.utils.encode_cell({ r: merge.s.r, c: merge.s.c });
                const endCell = XLSX.utils.encode_cell({ r: merge.e.r, c: merge.e.c });
                
                // 将合并区域的值统一为左上角单元格的值
                for (let row = merge.s.r; row <= merge.e.r; row++) {
                    for (let col = merge.s.c; col <= merge.e.c; col++) {
                        const cellAddress = XLSX.utils.encode_cell({ r: row, c: col });
                        if (!worksheet[cellAddress]) {
                        worksheet[cellAddress] = { ...worksheet[startCell] };
                        }
                    }
                }
            });
            }

            // 转换为 JSON
            this.jsonData = JSON.parse(JSON.stringify(XLSX.utils.sheet_to_json(worksheet, { defval: '' })))
            // console.log("xls数据",this.jsonData);
            this.tongdaoshebeiData = JSON.parse(JSON.stringify(XLSX.utils.sheet_to_json(worksheet, { defval: '' })))
            console.log("通道跟设备数据",this.tongdaoshebeiData);
            // this.xlsaddchannel()
            this.xlsAddDeviceGroup() //执行设备组、设备模板、设备子系列、数据区、数据项

           
            this.$refs.dianfileInput222.value = ""
            // 大致思路：
            // 1.新增模版组 （名称默认铭越外接）
            // 2.铭越外接模版组下有两个设备模板，第一个设备模板名称就是第一个通道对应的设备名，第二个设备模版名称就是环境
            // 3.设备子系列就根据设备名来确定，有多少个设备名就是多少个设备子系列(默认modbus设备)
            // 4.在地址里判断，根据读取地址，如果是连贯的，就创建一个数据区（名称默认数据区1），如果不是连贯的，那就是创建多少个不连贯的数据区（名称为变量名）
            // 5.先找出有多少通道需要新增（名称默认新通道+索引）
            // 6.新增通道成功后就需要新增设备，根据地址来判断需要新增几个设备（名称就是设备名+地址）设备需要默认重新生成变量
        };
        reader.readAsArrayBuffer(file);
        },
        // 执行新建通道跟新建设备
        async executeRequestsSequentially(requests) {
        const results = [];
        
        for (const request of requests) {
            try {
            // 等待当前请求完成
            if(request['类型'] == '通道'){
                // console.log("通道",request);
                var dd = {
                    "channel_name": "新通道"+request['序号'],
                    "channel_number": request['序号'],
                    "channel_type": 1,
                    "channel_protocol": 2,
                    "channel_interval": 100,
                    "port_type": 1,
                    "auto_open": 1,
                    "device_count": 10,
                    "serial_number": request['串口号'],
                    "baud_rate": 9600,
                    "parity": 0,
                    "data_bits": 8,
                    "stop_bits": 1
                }
                await channelconfigAdd(dd)
                // nowtongdaoObj
                await findchannelconfigAll().then(res => {
                    //  console.log("查询通道",res);
                     if(res != undefined && res[0]){
                         this.nowtongdaoObj = res.filter(item => item.channel_name == "新通道"+request['序号'])
                     }
                })
            }else {
                // console.log("设备",request,this.nowtongdaoObj);
                if(this.nowtongdaoObj.length != 0){
                    // waijieshebeizu
                    // console.log("this.waijieshebeizu",this.waijieshebeizu);
                    var mytemplate = []
                    mytemplate = this.waijieshebeizu[0].children.filter(item => item.device_template_name == request['设备名'])
                    
                    var resdevice_template = []
                    if(mytemplate.length != 0){
                        resdevice_template = mytemplate
                    }else {
                        resdevice_template = this.waijieshebeizu[0].children.filter(item => item.device_template_name == '环境')
                    }
                    // console.log("最终模板",resdevice_template);

                    var mydevice_serial_type = []
                    if(resdevice_template.length != 0){
                        mydevice_serial_type = resdevice_template[0].children.filter(item => item.serial_name == request['设备名']+'点表')
                    }
                    // console.log("最终子系列",mydevice_serial_type);
                    var dd = {
                        "channel_number": this.nowtongdaoObj[0].channel_number,
                        "device_number": request['序号'],
                        "device_name": request['设备名'],
                        "device_address": request['地址'],
                        "device_addressex": "0",
                        "device_group": this.waijieshebeizu[0].id,
                        "device_template": resdevice_template.length != 0 ? resdevice_template[0].id : 0,
                        "device_serial_type": mydevice_serial_type.length != 0 ? mydevice_serial_type[0].id : 0,
                        "device_protocol": 2,
                        "resend_count": 3,
                        "break_count": 1,
                        "run": 1,
                        "change": 1
                    }
                    // console.log("新增设备参数121",dd);
                    await addDevicechun(dd)
                }
            }
            // const response = await addDevicechun(request);
            // results.push(response);
            
            // 可选：更新 UI 或显示进度
            // this.progress = (results.length / requests.length) * 100;
            } catch (error) {
            // console.error('请求失败:', request, error);
            // 根据需求决定是否继续或中断
            // break; // 如果需要失败时停止，取消注释
            // results.push({ error: true, message: error.message });
            }
        }
        
        return results;
        },
        
        // 执行新建通道跟新建设备
        async startSequentialRequests(requestList) {
            // this.isMask = true;
            const results = await this.executeRequestsSequentially(requestList);
            this.$message({showClose: true,message: '操作成功',type: 'success'});
            this.isMask = false;
            // 处理最终结果
        },
        //外部xls表格新建通道
        xlsaddchannel(){
            // console.log("开始执行通道");
            var tongdao = []
            this.tongdaoshebeiData.forEach((item,index) => {
                tongdao.push({
                    '通道':item['通道'],
                    '串口号':item['串口号'],
                    '类型':"通道",
                    '设备':[]
                })
            })
            const uniqueArr = [...new Map(tongdao.map(item => [item['通道'], item])).values()];
           
            var myindex = -1
            this.tongdaoshebeiData.forEach(item => {
                uniqueArr.forEach(tt => {
                    if(tt['通道'] == item['通道']){
                        myindex = tt['设备'].findIndex(it => it['地址'] == item['地址'])
                        if(myindex == -1){
                            tt['设备'].push(item)
                        }
                     }
                 })
            })
            var chrequestList = []
            uniqueArr.forEach((item,ii) => {
                item['序号'] = this.gudingchannel_number + ii
                chrequestList.push(item)
                item['设备'].forEach((tt,index) => {
                     tt['类型'] = '设备'
                     tt['序号'] = (this.gudingchannel_numbershebei += 1)-1
                     chrequestList.push(tt)
                })
            })
            this.startSequentialRequests(chrequestList)
          

        },

        //外部xls表格新建设备组
        xlsAddDeviceGroup(){
            
            //组装一下需要新增的设备模板以及设备子系列、数据区、数据项
            var EquipmentTemplate = []
            this.jsonData.forEach(item => {
                EquipmentTemplate.push(item['设备名'])
            })
            EquipmentTemplate = [...new Set(EquipmentTemplate)]
            
            var GroupAndTemplate = [
                {
                    '设备模板':EquipmentTemplate[0],
                    '类型':'设备模板',
                    children:[
                        {
                            '设备子系列':EquipmentTemplate[0]+'点表',
                            '类型':'设备子系列',
                            '设备子系列原名':EquipmentTemplate[0],
                            children:[],
                        }
                    ]
                },
                {
                    '设备模板':'环境',
                    '类型':'设备模板',
                    children:[]
                },
            ]
            EquipmentTemplate.forEach((item,index) => {
                if(index != 0){
                     GroupAndTemplate[1].children.push({
                        '设备子系列':item+'点表',
                        '设备子系列原名':item,
                        '类型':'设备子系列',
                        children:[]
                     })
                }
            })
            var lianguan = []
            GroupAndTemplate.forEach(item => {
                 item.children.forEach(tt => {
                    lianguan = this.jsonData.filter(fit => fit['设备名'] == tt['设备子系列原名'])
                    tt.children = this.groupConsecutive(lianguan)//数据项
                    // console.log("循环机",tt,tt.children);
                    tt.children.forEach(tch => {
                        tch.forEach((tachfo,index) => {
                             tachfo['区内地址'] = index * 2
                        })
                    })
                 })
            })

            //递归，按照组装好的数组，依次拆出来组装成一个数组
            var newApiArr = []
           var recursiveFunction=function() {
                const getStr=function(list) {
                    list.forEach(function(row) {
                    if(row.children && row.children.length != 0) {
                        newApiArr.push(row)
                        getStr(row.children)
                    } else {
                        newApiArr.push(row)
                    }
                    })
                }
                getStr(GroupAndTemplate)
            }
            recursiveFunction()
            
            // console.log("GroupAndTemplate",GroupAndTemplate);
            // console.log("newApiArr",newApiArr);
            // return
            var d = {
              'device_group_name':"铭越外接"
            }
            // 先新增设备组
            this.isMask = true;
            addDeviceGroup(d).then(res => {
                if(res.code == 200){
                  //新增成功后需要查询设备组，来获取铭越外接的设备组id
                  findDeviceGroupListAll().then(resAll => {
                      if(resAll != undefined && typeof resAll == 'object'){
                        var waijie = resAll.filter(item => item.device_group_name == '铭越外接')
                        if(waijie.length != 0){
                            this.waijieshebeizu = waijie
                            this.startSequentialRequestsDeviceGroup(newApiArr)
                        }
                      }
                  })
                }
            })
            
        },
        //根据设备地址连贯性来分组
        groupConsecutive(arr) {
            if (arr.length === 0) return [];
            
            let result = [];
            let currentGroup = [arr[0]];
            
            for (let i = 1; i < arr.length; i++) {
                if (arr[i]['读取地址'] === arr[i-1]['读取地址'] + 1) {
                    // 如果当前项的dizhi是前一项+1，则添加到当前组
                    currentGroup.push(arr[i]);
                } else {
                    // 否则，将当前组添加到结果中，并开始新组
                    result.push(currentGroup);
                    currentGroup = [arr[i]];
                }
            }
            
            // 添加最后一个组
            result.push(currentGroup);
            return result;
        },
        // *执行设备模板跟设备子系列
        async executeRequestsSequentiallyDeviceGroup(requests) {
        const results = [];
        
        for (const request of requests) {
            try {
            // 等待当前请求完成
            const response = null
            var shebeizu = []
            if(request['类型'] == '设备模板'){
                // console.log("进入设备模板");
                var dd = {
                    "device_template_name":request['设备模板'],
                    "device_group_id":this.waijieshebeizu[0].id
                }
                this.device_template_name = request['设备模板']
                await addDeviceTemplate(dd)
                // await addDeviceTemplate(dd)
                // console.log("response1",response);
                // results.push(response);
               await findDeviceGroupListAll().then(resAll => {
                   shebeizu = resAll.filter(item => item.device_group_name == ['铭越外接'])
                   this.shebeizuArr = shebeizu
               })
            }else if(request['类型']== '设备子系列'){
            //    console.log("请求完设备组就需要查询一下",this.shebeizuArr);
               if(this.shebeizuArr.length != 0 && this.shebeizuArr[0].children != 0){
                 //获取设备模板，要添加相对应的设备子系列
                  var shebeimoban = this.shebeizuArr[0].children.filter(item => item.device_template_name == this.device_template_name)
                //   console.log("获取相对应的设备模版",shebeimoban);
                  if(shebeimoban.length != 0){
                    //开始新增设备子系列
                    var dd = {
                        "serial_name":request['设备子系列'],
                        "serial_type":1,
                        "device_template_id":shebeimoban[0].id
                    }
                    await addSerialType(dd)
                    //新增完设备子系列也需要重新查询一下
                    // shebeizixilieArr
                    await findDeviceGroupListAll().then(resAll => {
                        shebeizu = resAll.filter(item => item.device_group_name == ['铭越外接'])
                        var shebeimoban = shebeizu[0].children.filter(item => item.device_template_name == this.device_template_name)
                        // console.log("查看设备子系列",request);
                        this.nowshebeizixilieObj = request
                        // console.log("新增完设备子系列也需要重新查询一下",shebeimoban);
                        var shebeizixilie = []
                        if(shebeimoban.length != 0){
                            shebeizixilie = shebeimoban[0].children.filter(item => item.serial_name == request['设备子系列'])
                            this.shebeizixilieArr = shebeizixilie
                        }
                        // this.shebeizuArr = shebeizu
                    })
                  }
                  
               }
            //    console.log("设备模板名称",this.device_template_name);

                // console.log("查询设备跟设备模板",resAll);

                // 
               
            }else if(!request['类型']){
                //  console.log("查询相对应的设备子系列",this.shebeizixilieArr);
                 
                 //长度为1的话就是只有一个数据区，名称为遥测
                 if(this.nowshebeizixilieObj.children.length  == 1){
                    //先新增数据区
                    // console.log("只有一个数据区request",request);
                    var dd = {
                       "data_area_name":'遥测',
                        "data_area_addr":this.nowshebeizixilieObj.children[0][0]['读取地址'],
                        "read_code":3,
                        "write_code":0,
                        "data_area_len":request.length * 2,
                        "data_block_len":2,
                        "data_id_offset":0,
                        "device_serial_id":Number(this.shebeizixilieArr[0].id),
                        'area_type':0,
                    }
                    // console.log("数据区的参数",dd);
                    var noshujuqu = {}
                    await addModbusArea(dd)
                    await findAreaQuery(this.shebeizixilieArr[0].id).then(res => {
                         if(res != undefined && res[0]){
                            noshujuqu = res[0]
                         }
                    })
                    
                    var shujuxiangcanshu = []
                    var shujuleix = []
                    // console.log("requests查询数据项",request);
                    await request.forEach((item,index) => {
                         shujuleix = this.dataTypeList.filter(ait => ait.name == item['数据类型'])
                        //  console.log("数据类型,",shujuleix,item['数据类型']);
                        // area_addr
                         shujuxiangcanshu.push({
                            "area_id": noshujuqu.id,
                            "serial_id": Number(this.shebeizixilieArr[0].id),
                            "data_type":shujuleix.length == 0 ? 4 : shujuleix[0].value,
                            "app_type_group": 0,
                            "app_type": item['应用类型'],
                            "max_value": 0,
                            "min_value": 0,
                            "decimal": 0,
                            "coefficient": 0,
                            "offset": 0,
                            "zero": 0,
                            "memory_cycle": 300,
                            "event_over_limit": 0,
                            "event_alert_type": 0,
                            "sort": (index + 1),
                            "start_bit": 0,
                            "end_bit": 8,
                            "codify_type": 6,
                            "area_addr": item['区内地址'],
                            "data_len": 2,
                            "data_encoded": 1,
                            "data_name": item['变量名'],
                            "collect_coef": item['变量系数'] != 1 ? Number(item['变量系数'].toFixed(2)) : 0,
                            "data_number": 2,
                            "save": 1,
                            "reverse": 0,
                            "audio_alarm": 1,
                            "value_check": 0,
                            "alarm_print": 0,
                            "change_tip": 0,
                            "manual_value": 0,
                            "sampling": 1
                        })
                         
                    })
                   await this.startSequentialRequestsshujixiang(shujuxiangcanshu)
                   // 重新生成点号
                   await GenerateNumfn(Number(this.shebeizixilieArr[0].id))

                   
                 }
                 //长度不为1的话那就是有多个数据区，名称就是这些数据的变量名，然后数据项为自己的本身的变量名
                 if(this.nowshebeizixilieObj.children.length  != 1){
                     //先新增数据区 data_area_len
                    //  console.log("多个数据区request",request);
                    var dd = {
                       "data_area_name":request[0]['变量名'],
                        "data_area_addr":request[0]['读取地址'],
                        "read_code":3,
                        "write_code":0,
                        "data_area_len":2,
                        "data_block_len":2,
                        "data_id_offset":0,
                        "device_serial_id":Number(this.shebeizixilieArr[0].id),
                        'area_type':0,
                    }
                    await addModbusArea(dd)
                    //查询数据区
                    var shujuquArr = []
                    await findAreaQuery(this.shebeizixilieArr[0].id).then(res => {
                         if(res != undefined && res[0]){
                             shujuquArr = res
                         }
                    })
                    var dangqianshujuqu = shujuquArr.filter(item => item.data_area_name == request[0]['变量名'])
                    var shujuleix = []
                    if(dangqianshujuqu.length != 0){
                         shujuleix = this.dataTypeList.filter(ait => ait.name == request[0]['数据类型'])
                         var shujuxiangcanshu = [{
                            "area_id": dangqianshujuqu[0].id,
                            "serial_id": Number(this.shebeizixilieArr[0].id),
                            "data_type":  shujuleix.length == 0 ? 4 : shujuleix[0].value,
                            "app_type_group": 0,
                            "app_type": request[0]['应用类型'],
                            "max_value": 0,
                            "min_value": 0,
                            "decimal": 0,
                            "coefficient": 0,
                            "offset": 0,
                            "zero": 0,
                            "memory_cycle": 300,
                            "event_over_limit": 0,
                            "event_alert_type": 0,
                            "sort": 1,
                            "start_bit": 0,
                            "end_bit": 8,
                            "codify_type":6,
                            "area_addr": request[0]['区内地址'],
                            "data_len": 2,
                            "data_encoded": 1,
                            "data_name": request[0]['变量名'],
                            "collect_coef": request[0]['变量系数'] != 1 ? Number(request[0]['变量系数'].toFixed(2)) : 0,
                            "data_number": 2,
                            "save": 1,
                            "reverse": 0,
                            "audio_alarm": 1,
                            "value_check": 0,
                            "alarm_print": 0,
                            "change_tip": 0,
                            "manual_value": 0,
                            "sampling": 1
                        }]
                        await this.startSequentialRequestsshujixiang(shujuxiangcanshu)
                         // 重新生成点号
                        await GenerateNumfn(Number(this.shebeizixilieArr[0].id))
                    }

                 }
            }
            } catch (error) {
            // console.error('请求失败:', request, error);
            // 根据需求决定是否继续或中断
            // break; // 如果需要失败时停止，取消注释
            // results.push({ error: true, message: error.message });
            }
        }
        
        return results;
        },
        
        // *执行设备模板跟设备子系列
        async startSequentialRequestsDeviceGroup(requestList) {
            // this.isMask = true;
            const results = await this.executeRequestsSequentiallyDeviceGroup(requestList);
            // console.log("执行全部数据区数据项完毕后才开始执行通道");
            findDeviceGroupListAll().then(resAll => {
                if(resAll != undefined && typeof resAll == 'object'){
                   var waijie = resAll.filter(item => item.device_group_name == '铭越外接')
                  if(waijie.length != 0){
                        this.waijieshebeizu = waijie
                     this.xlsaddchannel()
                  }
               }
            })
            
            this.isMask = false;
            // 处理最终结果
        },

        //*外部xls表格新建数据项
        async executeRequestsSequentiallyshujuxiang(requests) {
            const results = [];
            
            for (const request of requests) {
                try {
                // 等待当前请求完成
                const response = await addModbusItem(request);
                results.push(response);
                
                // 可选：更新 UI 或显示进度
                // this.progress = (results.length / requests.length) * 100;
                } catch (error) {
                // console.error('请求失败:', request, error);
                // 根据需求决定是否继续或中断
                // break; // 如果需要失败时停止，取消注释
                // results.push({ error: true, message: error.message });
                }
            }
            
            return results;
        },
        
        // *执行xls表格新建数据项
        async startSequentialRequestsshujixiang(requestList) {
            // this.isMask = true;
            const results = await this.executeRequestsSequentiallyshujuxiang(requestList);
            // this.isMask = false;
            // 处理最终结果
        },


        
        
  },
};
</script>
<style lang="scss" scoped>
    .Excelview {
         width: 100%;
         height: 100%;
         .con {
             width: 100%;
             height: 100%;
             background-color: #fff;
             padding: 30px;
             box-sizing: border-box;
             position: relative;
         }
    }
</style>